package com.zmkm.project.dbserver.utils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.HttpHostConnectException;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.alibaba.fastjson.JSON;
import com.zmkm.project.dbserver.constant.NumberContant;

/**
 * 〈一句话功能简述〉httpClient客户端工具类
 * 〈功能详细描述〉
 * 
 * @author duanhy
 * @version [版本号, 2015年11月2日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class HttpClientUtils {
    /** 日志器 */
    private static Logger logger = LogManager.getLogger(HttpClientUtils.class);
    
    /** 客户端构建器 */
    private static HttpClientBuilder builder = null;
    
    /** 客户端类 */
    private static CloseableHttpClient client = null;
    
    /** 请求配置 */
    private static RequestConfig requestConfig = initConfig();
    
    /** 初始化开关 **/
    private static boolean isInit = false;
    
    /** socket超时时间 */
    private static int socketTimeout = 300000;
    
    /** 链接时间 */
    private static int connectTimeout = 300000;
    
    /** 链接请求时间 */
    private static int connectionRequestTimeout = 300000;
    
    /** 检测链接是否可用 */
    private static boolean staleConnectionCheckEnabled = true;
    
    /**
     * 〈一句话功能简述〉post请求
     * 〈功能详细描述〉
     * 
     * @param url 请求地址
     * @param map 请求参数
     * @return 响应结果
     * @throws Exception 客户端异常
     * @see [类、类#方法、类#成员]
     */
    public static ResultMessage doPost(String url, Map<String, Object> map)
        throws Exception {
        if (StringUtils.isEmpty(url)) {
            return null;
        }
        ResultMessage msg = null;
        HttpPost post = new HttpPost(url);
        // RequestConfig requestConfig = initConfig();
        post.setConfig(requestConfig);
        List<NameValuePair> formParams = new ArrayList<NameValuePair>();
        if (null != map) {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                if (logger.isDebugEnabled()) {
                    logger.debug("key= " + entry.getKey() + " and value= "
                        + entry.getValue());
                }
                String temp = null != entry.getValue()
                    ? entry.getValue().toString() : null;
                formParams.add(new BasicNameValuePair(entry.getKey(), temp));
            }
            UrlEncodedFormEntity entity =
                new UrlEncodedFormEntity(formParams, "UTF-8");
            post.setEntity(entity);
        }
        msg = getMessage(post);
        return msg;
    }
    
    /**
     * 〈一句话功能简述〉get请求
     * 〈功能详细描述〉
     * 
     * @param url 请求路径
     * @return 响应结果
     * @throws Exception 客户端异常
     * @see [类、类#方法、类#成员]
     */
    public static ResultMessage doGet(String url)
        throws Exception {
        
        if (StringUtils.isEmpty(url)) {
            return null;
        }
        // 创建httpget.
        HttpGet get = new HttpGet(url);
        // RequestConfig requestConfig = initConfig();
        get.setConfig(requestConfig);
        if (logger.isDebugEnabled()) {
            logger.debug("executing request " + get.getURI());
        }
        return getMessage(get);
    }
    
    /**
     * 〈一句话功能简述〉delete请求
     * 〈功能详细描述〉
     * 
     * @param url 请求路径
     * @return 响应结果
     * @throws Exception 客户端异常
     * @see [类、类#方法、类#成员]
     */
    public static ResultMessage doDelete(String url)
        throws Exception {
        ResultMessage msg = null;
        HttpDelete delete = new HttpDelete(url);
        // RequestConfig requestConfig = initConfig();
        delete.setConfig(requestConfig);
        
        CloseableHttpResponse response = null;
        try {
            response = getHttpClient().execute(delete);
            HttpEntity entity = response.getEntity();
            int status = response.getStatusLine().getStatusCode();
            logger.info("status:" + status);
            if (status == HttpStatus.SC_OK) {
                // 判断响应实体是否为空
                if (entity != null) {
                    String data = EntityUtils.toString(entity);
                    if (logger.isDebugEnabled()) {
                        logger.debug("contentEncoding:"
                            + entity.getContentEncoding() + "/ndata:" + data);
                    }
                    msg = JSON.parseObject(data, ResultMessage.class);
                }
            }
            else {
                delete.abort();
            }
        }
        catch (Exception ex) {
            msg = null;
            logger.error(ex);
        }
        finally {
            close(response);
        }
        
        return msg;
    }
    
    /**
     * 〈一句话功能简述〉请求超时对象设置
     * 〈功能详细描述〉
     * 
     * @return 请求超时对象
     * @see [类、类#方法、类#成员]
     */
    @SuppressWarnings("deprecation")
    public static RequestConfig initConfig() {
        RequestConfig requestConfig = RequestConfig.custom()
            .setSocketTimeout(socketTimeout)
            .setConnectTimeout(connectTimeout)
            .setConnectionRequestTimeout(connectionRequestTimeout)
            .setStaleConnectionCheckEnabled(staleConnectionCheckEnabled)
            .build();
        return requestConfig;
    }
    
    /**
     * 
     * 〈一句话功能简述〉初始化客户端
     * 〈功能详细描述〉
     * 
     * @see [类、类#方法、类#成员]
     */
    private static synchronized void initClient() {
        if (!isInit) {
            builder = HttpClientBuilder.create();
            client = builder.build();
        }
    }
    
    /**
     * 
     * 〈一句话功能简述〉获取客户端
     * 〈功能详细描述〉
     * 
     * @return CloseableHttpClient 客户端
     * @see [类、类#方法、类#成员]
     */
    private static synchronized CloseableHttpClient getHttpClient() {
        if (client == null) {
            initClient();
        }
        return client;
    }
    
    /**
     * 〈一句话功能简述〉关闭连接
     * 〈功能详细描述〉
     * 
     * @throws IOException 关闭异常
     * 
     * @see [类、类#方法、类#成员]
     */
    private static void close(CloseableHttpResponse response)
        throws IOException {
        if (response != null) {
            response.close();
        }
    }
    
    // /**
    // * 获取请求响应的内容
    // *
    // * @param request 请求
    // * @return 响应结果 JSON格式
    // * @throws Exception 客户端异常
    // * @see [类、类#方法、类#成员]
    // */
    // private static ResultMessage getMessage(HttpUriRequest request) {
    // ResultMessage msg = null;
    // CloseableHttpResponse response = null;
    // try {
    // response = getHttpClient().execute(request);
    // int status = response.getStatusLine().getStatusCode();
    // if (status == HttpStatus.SC_OK) {
    // HttpEntity httpEntity = response.getEntity();
    // // 判断响应实体是否为空
    // if (httpEntity != null) {
    // String data = EntityUtils.toString(httpEntity);
    // if (logger.isDebugEnabled()) {
    // logger.debug("contentEncoding:"
    // + httpEntity.getContentEncoding() + "/ndata:"
    // + data);
    // }
    // msg = JSON.parseObject(data, ResultMessage.class);
    // }
    // }
    // else {
    // request.abort();
    // }
    // }
    // catch (Exception ex) {
    // logger.error(ex);
    // if (ex instanceof HttpHostConnectException) {
    // msg = new ResultMessage();
    // msg.setCode(-3);
    // }
    // }
    // finally {
    // try {
    // close(response);
    // }
    // catch (IOException e) {
    // logger.error(e);
    // }
    // }
    //
    // return msg;
    // }
    /**
     * 获取请求响应的内容
     * 
     * @param request 请求
     * @return 响应结果 JSON格式
     * @throws Exception 客户端异常
     * @see [类、类#方法、类#成员]
     */
    private static ResultMessage getMessage(HttpUriRequest request) {
        ResultMessage msg = null;
        CloseableHttpResponse response = null;
        try {
            response = getHttpClient().execute(request);
            int status = response.getStatusLine().getStatusCode();
            if (status == HttpStatus.SC_OK) {
                HttpEntity httpEntity = response.getEntity();
                // 判断响应实体是否为空
                if (httpEntity != null) {
                    String data = EntityUtils.toString(httpEntity);
                    if (logger.isDebugEnabled()) {
                        logger.debug(
                            "contentEncoding:" + httpEntity.getContentEncoding()
                                + "/ndata:" + data);
                    }
                    // msg = JSON.parseObject(data, ResultMessage.class);
                    if (null != data) {
                        msg = new ResultMessage();
                        msg.setData(data);
                        msg.setCode(NumberContant.ONE);
                    }
                }
            }
            else {
                request.abort();
            }
        }
        catch (Exception ex) {
            logger.error(ex);
            if (ex instanceof HttpHostConnectException) {
                msg = new ResultMessage();
                msg.setCode(-3);
            }
        }
        finally {
            try {
                close(response);
            }
            catch (IOException e) {
                logger.error(e);
            }
        }
        System.out.println();
        return msg;
    }
}
